package com.zg.autoflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zg.autoflow.dao.mapper.AutoFlowBusinessMapper;
import com.zg.autoflow.enm.FlowContants;
import com.zg.autoflow.req.SettleWorkflowReq;
import com.zg.autoflow.service.SettleWorkflowService;
import com.zg.autoflow.vo.SettleWorkflowVo;
import com.zg.common.core.User;
import com.zg.common.core.dao.BaseEntity;
import com.zg.common.core.dao.autoflow.dao.*;
import com.zg.common.core.dao.autoflow.entity.*;
import com.zg.common.core.dao.autoflow.mapper.SettleBizmodelMapper;
import com.zg.common.core.dao.autoform.DiyForm;
import com.zg.common.core.dao.autoform.DiyFormDao;
import com.zg.common.core.dao.autoform.DiyView;
import com.zg.common.core.dao.autoform.DiyViewDao;
import com.zg.common.core.util.CollectionUtils;
import com.zg.common.web.Req;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
* @author zg
*/
@Service
@RequiredArgsConstructor
public class SettleWorkflowServiceImpl implements SettleWorkflowService {

    private final SettleWorkflowDao settleWorkflowDao;
    private final SettleWorkflowUserDao settleWorkflowUserDao;
    private final AutoflowStepSealdataDao autoflowStepSealdataDao;
    private final AutoflowStepDao autoflowStepDao;
    private final DiyFormDao diyFormDao;
    private final SettleBizmodelDao settleBizmodelDao;
    private final SettleBizmodelMapper settleBizmodelMapper;
    private final AutoflowMainDao autoflowMainDao;
    private final SettleWorkflowStepDao settleWorkflowStepDao;
    private final AutoflowStepPersonDao autoflowStepPersonDao;
    private final AutoflowStepSubDao autoflowStepSubDao;
    private final SettleWorkflowSubDao settleWorkflowSubDao;
    private final SettleWorkflowStepSubDao settleWorkflowStepSubDao;
    private final AutoflowStepSubPersonDao autoflowStepSubPersonDao;
    private final SettleWorkflowStepSubUserDao settleWorkflowStepSubUserDao;
    private final AutoflowSubDao autoflowSubDao;
    private final SFlowStepUserDao sFlowStepUserDao;
    private final AutoflowStepFormDao autoflowStepFormDao;
    private final AutoFlowBusinessMapper autoFlowBusinessMapper;


    @Override
    public Page<SettleWorkflow> page(SettleWorkflowReq settleWorkflowReq) {
        // 获取当前登录用户ID
        User currentUser = Req.getCurrUser();
        String userId = String.valueOf(currentUser.getId());

        // 查询当前用户下的流程信息
        LambdaQueryWrapper<SettleWorkflowUser> settleWorkflowUserQueryWrapper = new LambdaQueryWrapper<>();
        settleWorkflowUserQueryWrapper.eq(SettleWorkflowUser::getUserId, userId);

        List<SettleWorkflowUser> settleWorkflowUserList = settleWorkflowUserDao.list(settleWorkflowUserQueryWrapper);

        // 如果用户没有流程权限，返回空结果
        if (settleWorkflowUserList.size() == 0) {
            return new Page<>(settleWorkflowReq.getPage(), settleWorkflowReq.getPageSize());
        }

        // 获取用户有权限的流程编码列表
        Set<String> flowCodeList = new HashSet<>();
        for (SettleWorkflowUser user : settleWorkflowUserList) {
            flowCodeList.add(user.getFlowCode());
        }

        // 构建查询条件
        LambdaQueryWrapper<SettleWorkflow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SettleWorkflow::getFlowCode, flowCodeList);
        queryWrapper.eq(SettleWorkflow::getCanStart, "Y");
        queryWrapper.eq(SettleWorkflow::getDeleteState, "0");
        if (settleWorkflowReq.getFlowName() != null) {
            queryWrapper.like(SettleWorkflow::getFlowName, "%" + settleWorkflowReq.getFlowName() + "%");
        }
        if (settleWorkflowReq.getFlowCode() != null) {
            queryWrapper.like(SettleWorkflow::getFlowCode, "%" + settleWorkflowReq.getFlowCode() + "%");
        }

        // 分页查询
        Page<SettleWorkflow> pageInfo = settleWorkflowDao.page(new Page<>(settleWorkflowReq.getPage(), settleWorkflowReq.getPageSize()), queryWrapper);

        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncAutoFlow(AutoflowMain autoflow) {
        //盖章信息
        LambdaQueryWrapper<AutoflowStepSealdata> queryWrapper4 = new LambdaQueryWrapper<>();
        queryWrapper4.eq(AutoflowStepSealdata::getFlowCode,autoflow.getCode());
        List<AutoflowStepSealdata> list1 = autoflowStepSealdataDao.list(queryWrapper4);
        Map<String, AutoflowStepSealdata> stringAutoflowStepSealdataMap = CollectionUtils.collectionToMap(list1, AutoflowStepSealdata::getStepCode);

        List<AutoflowStep> stepByFlowId = autoflowStepDao.list(new LambdaQueryWrapper<AutoflowStep>().eq(AutoflowStep::getFlowId,autoflow.getId()).eq(BaseEntity::getIsDel,false));
        //所有的表单
        Set<Long> stepIds = CollectionUtils.getObjectAttributeSet(stepByFlowId, AutoflowStep::getId);
        List<AutoflowStepForm> formList = autoflowStepFormDao.list(new LambdaQueryWrapper<AutoflowStepForm>().in(AutoflowStepForm::getStepId,stepIds));
        Set<Long> formids = formList.stream().map(AutoflowStepForm::getFormId).collect(Collectors.toSet());
        List<DiyForm> autoformMaims = diyFormDao.listByIds(formids);
        List<String> formIds = autoformMaims.stream().map(line -> {
            return line.getId() + "";
        }).distinct().collect(Collectors.toList());
        autoFlowBusinessMapper.delSettleBizmodel(formIds);
//        同步所有的表单
        List<SettleBizmodel> SettleBizmodels = new ArrayList<>();
        for (DiyForm autoformMaim : autoformMaims) {
            SettleBizmodel settleBizmodel = new SettleBizmodel();
            settleBizmodel.setCreateDate(new Date());
            settleBizmodel.setBizzTable(autoformMaim.getCode());
            settleBizmodel.setModelCode(autoformMaim.getId()+"");
            settleBizmodel.setFormType(autoformMaim.getCode());
            settleBizmodel.setFormUrl("/html_settle_workflow/form_preview.html?AUTOFORM_ID=" + autoformMaim.getId());
            settleBizmodel.setIsMain("1");
            settleBizmodel.setModelName(autoformMaim.getName());
            SettleBizmodels.add(settleBizmodel);
        }
        settleBizmodelDao.saveBatch(SettleBizmodels);
        autoflow.setState("5");
        //更新状态
        autoflowMainDao.updateById(autoflow);
        //删除流程
        String code = autoflow.getCode();
        autoFlowBusinessMapper.delSettleWorkflowByCode(code);
        autoFlowBusinessMapper.delSettleWorkflowStepByCode(code);
        autoFlowBusinessMapper.delSettleWorkflowUserByCode(code);
        AutoflowStep startStep = null;

        for (int i = 0; i < stepByFlowId.size(); i++) {
            AutoflowStep step = stepByFlowId.get(i);
            if (step.getStepNo().equals(FlowContants.StepCode.STEP_START)) {
                startStep = step;
                break;
            }
        }
        QueryWrapper<AutoflowStepPerson> query = new QueryWrapper<>();
        query.lambda().eq(AutoflowStepPerson::getStepId, startStep.getId());
        //流程处理人
        List<AutoflowStepPerson> startStepPersons = autoflowStepPersonDao.list(query);
        for (AutoflowStepPerson  p : startStepPersons) {
            SettleWorkflowUser settleWorkflowUser = new SettleWorkflowUser();
            settleWorkflowUser.setFlowCode(autoflow.getCode());
            settleWorkflowUser.setUserId(p.getStepHandler());
            settleWorkflowUserDao.save(settleWorkflowUser);
        }
        //同步流程
        SettleWorkflow settleWorkflow = new SettleWorkflow();
        settleWorkflow.setFlowCode(autoflow.getCode());
        settleWorkflow.setNextFlowCode(autoflow.getNextFlowCode());
        settleWorkflow.setNextAuthUser(autoflow.getNextAuthUser());
        settleWorkflow.setFlowName(autoflow.getName());
        settleWorkflow.setFlowType(autoflow.getType());
        settleWorkflow.setCanStart(autoflow.getCanStart());
        settleWorkflowDao.save(settleWorkflow);
        //同步流程步骤
        List<SettleWorkflowStep> steps = new ArrayList<>();
        Map<Long, DiyForm> longAutoformMaimMap = CollectionUtils.collectionToMap(autoformMaims, DiyForm::getId);
        List<SFlowStepUser> sFlowStepUsers = new ArrayList<>();
        for (AutoflowStep step : stepByFlowId) {
            SettleWorkflowStep settleStep = new SettleWorkflowStep();
            settleStep.setFlowCode(autoflow.getCode());
            settleStep.setBillStep(step.getBillStep());
            settleStep.setApproveType(step.getApproveType());
            settleStep.setIsStepEnd(step.getIsStepEnd());
            settleStep.setCanBack(step.getIsReturn());
            settleStep.setCanBeBack(step.getIsReturned());
            settleStep.setCanReEdit(step.getIsEdit());
            settleStep.setCanApp(step.getCanApp());
            List<AutoflowStepForm> formList1 = autoflowStepFormDao.list(new LambdaQueryWrapper<AutoflowStepForm>().eq(AutoflowStepForm::getStepId, step.getId()));
            if (!CollectionUtils.isEmpty(formList1)){
                String formId = formList1.stream().map(line -> {
                    return line.getFormId() + "";
                }).collect(Collectors.joining(","));
                settleStep.setModelCode(formId);
            }
            settleStep.setStepParameter(step.getStepParameter());
            DiyForm autoformMaim = longAutoformMaimMap.get(step.getStepFormId());
            if (autoformMaim != null) {
                settleStep.setModelCode(autoformMaim.getCode());
            }
            //盖章信息
            AutoflowStepSealdata autoflowStepSealdata = stringAutoflowStepSealdataMap.get(step.getStepNo());
            if(autoflowStepSealdata!=null)
            {
                settleStep.setSealData(autoflowStepSealdata.getSealData());
            }
            settleStep.setSeq(step.getSeq());
            settleStep.setMustSeal(step.getIsSeal());
            settleStep.setNextStep(step.getNextStepId());
            settleStep.setStepCode(step.getStepNo());
            settleStep.setStepFlag(step.getStepFlag());
            settleStep.setStepName(step.getStepName());
            settleStep.setCreateDate(new Date());
            settleStep.setIsUse("0");
            settleStep.setIsBegin(FlowContants.StepCode.STEP_START.equals(step.getStepNo()) ? "1" : "");
            settleStep.setIsEnd(FlowContants.StepCode.STEP_OVER.equals(step.getStepNo()) ? "1" : "");
            settleStep.setSelectHandlerMode(step.getSelectHandlerMode());
            settleStep.setShortMessage(step.getShortMessage());
            settleStep.setShortMessageType(step.getShortMessageType());
            settleStep.setIsBackApproval(step.getIsBackApproval());
            steps.add(settleStep);
            QueryWrapper<AutoflowStepPerson> queryStepPerson = new QueryWrapper<>();
            queryStepPerson.lambda().eq(AutoflowStepPerson::getStepId, step.getId());
            List<AutoflowStepPerson> stepHandlerByStepId = autoflowStepPersonDao.list(queryStepPerson);
            //环节处理人
            for (AutoflowStepPerson p : stepHandlerByStepId) {
                SFlowStepUser flowStepUser = new SFlowStepUser();
                flowStepUser.setFlowCode(autoflow.getCode());
                flowStepUser.setStepCode(step.getStepNo());
                flowStepUser.setOperUser(p.getStepHandler().toString());
                flowStepUser.setOperOrg(p.getStepHandlerOrg());
                sFlowStepUsers.add(flowStepUser);
            }

        }
        autoFlowBusinessMapper.delFlowStepUserByCode(autoflow.getCode());
        //插入新数据
        if (sFlowStepUsers.size() > 0) {
            sFlowStepUserDao.saveBatch(sFlowStepUsers);
        }
        settleWorkflowStepDao.saveBatch(steps);



        //子流程
        //清空子流程配置
        autoFlowBusinessMapper.delSettleWorkflowSubByCode(autoflow.getCode());
        autoFlowBusinessMapper.delSettleWorkflowStepSubByCode(autoflow.getCode());
        autoFlowBusinessMapper.delSettleWorkflowStepSubUserByCode(autoflow.getCode());
        //拷贝新配置
        {
            LambdaQueryWrapper<AutoflowSub> queryWrapper3 = new LambdaQueryWrapper<>();
            queryWrapper3.eq(AutoflowSub::getFlowCode,autoflow.getCode());
            List<AutoflowSub> list = autoflowSubDao.list(queryWrapper3);
            if(list.size()>0)
            {
                List<SettleWorkflowSub> listse = new ArrayList<>();
                for (AutoflowSub as:list   ) {
                    SettleWorkflowSub settleWorkflowSub = new SettleWorkflowSub();
                    settleWorkflowSub.setId(as.getId());
                    settleWorkflowSub.setField(as.getField());
                    settleWorkflowSub.setFlowCode(as.getFlowCode());
                    settleWorkflowSub.setField2(as.getField2());
                    settleWorkflowSub.setName(as.getName());
                    settleWorkflowSub.setFieldValue(as.getFieldValue());
                    settleWorkflowSub.setField2Value(as.getField2Value());
                    listse.add(settleWorkflowSub);
                }
                settleWorkflowSubDao.saveBatch(listse);
            }
        }
        {
            LambdaQueryWrapper<AutoflowStepSub> queryWrapper3 = new LambdaQueryWrapper<>();
            queryWrapper3.eq(AutoflowStepSub::getFlowCode,autoflow.getCode());
            List<AutoflowStepSub> list = autoflowStepSubDao.list(queryWrapper3);
            if(list.size()>0)
            {
                List<SettleWorkflowStepSub> listse = new ArrayList<>();
                for (AutoflowStepSub as:list   ) {
                    SettleWorkflowStepSub settleWorkflowSub = new SettleWorkflowStepSub();
                    settleWorkflowSub.setId(as.getId());
                    settleWorkflowSub.setFlowCode(as.getFlowCode());
                    settleWorkflowSub.setStepName(as.getStepName());
                    settleWorkflowSub.setNextStepId(as.getNextStepId());
                    settleWorkflowSub.setStepNo(as.getStepNo());
                    settleWorkflowSub.setSubFlowId(as.getSubFlowId());
                    listse.add(settleWorkflowSub);
                }
                settleWorkflowStepSubDao.saveBatch(listse);
            }
        }
        {
            LambdaQueryWrapper<AutoflowStepSubPerson> queryWrapper3 = new LambdaQueryWrapper<>();
            queryWrapper3.eq(AutoflowStepSubPerson::getFlowCode,autoflow.getCode());
            List<AutoflowStepSubPerson> list = autoflowStepSubPersonDao.list(queryWrapper3);
            if(list.size()>0)
            {
                List<SettleWorkflowStepSubUser> listse = new ArrayList<>();
                for (AutoflowStepSubPerson as:list   ) {
                    SettleWorkflowStepSubUser settleWorkflowSub = new SettleWorkflowStepSubUser();
                    settleWorkflowSub.setId(as.getId());
                    settleWorkflowSub.setFlowCode(as.getFlowCode());
                    settleWorkflowSub.setStepCode(as.getStepCode());
                    settleWorkflowSub.setSubFlowId(as.getSubFlowId());
                    settleWorkflowSub.setStepHandler(as.getStepHandler());
                    settleWorkflowSub.setStepHandlerOrg(as.getStepHandlerOrg());
                    listse.add(settleWorkflowSub);
                }
                settleWorkflowStepSubUserDao.saveBatch(listse);
            }
        }
//        //清空redis
//        clearRedis(autoflow.getCode());
//        //人员
//        stepUserService.clearRedis(autoflow.getCode());
//        //环节
//        settleWorkflowStepService.clearRedis(autoflow.getCode());
    }
}
